package com.keba.lamp.complaint.service.impl;


import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.keba.basic.context.ContextUtil;
import com.keba.basic.database.mybatis.conditions.Wraps;
import com.keba.basic.utils.BeanPlusUtil;
import com.keba.basic.utils.DateUtils;
import com.keba.lamp.common.constant.AppendixType;
import com.keba.lamp.complaint.entity.DocTemplate;
import com.keba.lamp.complaint.enumeration.DocTemplateTypeEnum;
import com.keba.lamp.complaint.service.DocTemplateService;
import com.keba.lamp.file.service.AppendixService;
import com.keba.lamp.file.service.FileService;
import com.keba.lamp.file.vo.param.FileUploadVO;
import com.keba.lamp.file.vo.result.FileResultVO;
import com.keba.lamp.model.vo.result.AppendixResultVO;
import com.keba.lamp.model.vo.save.AppendixSaveVO;
import com.keba.lamp.office.properties.WebOfficeProperties;
import com.keba.lamp.office.service.OfficeApiFacade;
import com.keba.lamp.office.vo.*;
import com.keba.lamp.system.entity.tenant.DefUser;
import com.keba.lamp.system.service.tenant.DefUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class OfficeApiFacadeImpl implements OfficeApiFacade {
    private final WebOfficeProperties officeProperties;

    private final FileService fileService;

    private final AppendixService appendixService;

    private final DefUserService defUserService;

    private final DocTemplateService docTemplateService;


    @Override
    public OfficeFileVO getOffice(String fileId) {
        log.info("开始获取office文件getOffice fileId: {}", fileId);
        DocTemplate docTemplate = docTemplateService.getById(Convert.toLong(fileId));
        //LocalDateTime 转换成 时间戳
        //文档创建时间戳，单位纪元秒
        String extName = FileUtil.extName(docTemplate.getName());
        return OfficeFileVO.builder().id(fileId).name(StrUtil.isBlank(extName) ? docTemplate.getName() + ".docx" : docTemplate.getName())
                .size(docTemplate.getSize()).version(docTemplate.getVersion())
                .create_time(Convert.toInt(docTemplate.getCreatedTime().atZone(ZoneOffset.UTC).toEpochSecond()))
                .modify_time(Convert.toInt(docTemplate.getUpdatedTime().atZone(ZoneOffset.UTC).toEpochSecond()))
                .creator_id(Convert.toStr(docTemplate.getCreatedBy(), "2")).modifier_id(Convert.toStr(docTemplate.getUpdatedBy(), "2")).build();
    }

    @Override
    public OfficeFileDownloadVO download(String fileId) {
        OfficeFileDownloadVO officeFileDownloadVO = new OfficeFileDownloadVO().setUrl(officeProperties.getTemplateUrl());
        DocTemplate docTemplate = docTemplateService.getById(Convert.toLong(fileId));
        AppendixResultVO appendixResultVO = appendixService.getByBiz(Convert.toLong(fileId), Objects.isNull(docTemplate.getCaseId()) ? AppendixType.Complaint.COMPLAINT__OFFICE__FILE : DocTemplateTypeEnum.getByCode(docTemplate.getDocTemplateType()).getDesc());
        if (Objects.isNull(appendixResultVO)) {
            log.info("未找到office文件返回默认URL，fileId: {}", fileId);
            return officeFileDownloadVO;
        }
        officeFileDownloadVO.setUrl(fileService.findUrlById(appendixResultVO.getId()));
        log.info("office文件下载地址：{}", officeFileDownloadVO.getUrl());
        return officeFileDownloadVO;
    }

    @Override
    public List<OfficeUserVO> getUser(List<Long> userId) {
        List<DefUser> defUsers = defUserService.listByIds(userId);
        return defUsers.stream().map(defUser -> {
            return OfficeUserVO.builder().id(defUser.getId().toString()).name(defUser.getNickName()).build();
        }).collect(Collectors.toList());
    }

    @Override
    public OfficePermissionVO getPermission(Long fileId) {
        log.info("获取office文件权限getPermission  userId:{} fileId:{}", ContextUtil.getUserId(), fileId);
        return OfficePermissionVO.builder().user_id(Convert.toStr(ContextUtil.getUserId())).print(1).read(1).print(1).update(1).copy(1).download(1).build();
    }

    @Override
    public OfficeFileVO saveOffice(String fileId, MultipartFile file) {
        log.info("开始保存office文件saveOffice fileId: {}, fileName: {}", fileId, file.getOriginalFilename());
        return OfficeFileVO.builder().id(fileId).name(file.getName()).size(Convert.toInt(file.getSize())).version(0).create_time(Convert.toInt(DateUtil.current())).modify_time(Convert.toInt(DateUtil.current())).creator_id("1").modifier_id("1").build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadOffice(InputStream file, String fileId, String fileName, Integer fileSize, String userId) {
        fileName = URLDecoder.decode(fileName, Charset.defaultCharset());
        log.info("===开始上传Office文件：{}", fileName);
        // 保存文件到本地
        DocTemplate docTemplate = docTemplateService.getById(Convert.toLong(fileId));

        FileUploadVO fileUploadVO = new FileUploadVO();
        fileUploadVO.setBizType(AppendixType.Complaint.COMPLAINT__OFFICE__FILE);
        if (Objects.nonNull(docTemplate.getCaseId())) {
            fileUploadVO.setBizType(DocTemplateTypeEnum.getByCode(docTemplate.getDocTemplateType()).getDesc());
        }
        FileResultVO fileResultVO = fileService.upload(file, fileName, fileUploadVO);
        // 保存文件信息到数据库
        AppendixSaveVO appendixSaveVO = AppendixSaveVO.build(Convert.toLong(fileId), AppendixType.Complaint.COMPLAINT__OFFICE__FILE, fileResultVO.getId());
        if (Objects.nonNull(docTemplate.getCaseId())) {
            appendixSaveVO = AppendixSaveVO.build(Convert.toLong(fileId), AppendixSaveVO.TypeFile.build(DocTemplateTypeEnum.getByCode(docTemplate.getDocTemplateType()).getDesc(), fileResultVO.getId()));
        }
        appendixService.save(appendixSaveVO);
        docTemplate.setName(fileName).setSize(fileSize).setVersion(docTemplate.getVersion() + 1).setUpdatedBy(Convert.toLong(userId));
        docTemplateService.getSuperManager().updateById(docTemplate.setEditStatus(Boolean.TRUE));
        log.info("===结束上传Office文件：{}", fileName);
    }

    @Override
    public OfficeInitVO initOffice(OfficeQueryVO queryVO) {
        //案件为空的说明是标准模版新增或者编辑
        if (Objects.nonNull(queryVO.getId()) && Objects.isNull(queryVO.getCaseId())) {
            DocTemplate docTemplate = docTemplateService.getById(queryVO.getId());
            AppendixResultVO appendixResultVO = appendixService.getByBiz(docTemplate.getId(), AppendixType.Complaint.COMPLAINT__OFFICE__FILE);
            return OfficeInitVO.builder().appId(officeProperties.getAppId()).fileId(docTemplate.getId().toString()).url(fileService.findUrlById(appendixResultVO.getId())).build();
        }
        if (Objects.nonNull(queryVO.getCaseId())) {
            DocTemplate docTemplate = docTemplateService.getSuperManager().getOne(Wraps.<DocTemplate>lbQ().eq(DocTemplate::getCaseId, queryVO.getCaseId())
                    .eq(DocTemplate::getParentDocTemplateId, queryVO.getId())
                    .eq(DocTemplate::getDocType, queryVO.getDocType()).eq(DocTemplate::getApplyParty, queryVO.getApplyParty())
                    .eq(DocTemplate::getPartyType, queryVO.getPartyType()).eq(DocTemplate::getCaseUserId, queryVO.getCaseUserId())
                    .eq(DocTemplate::getDocTemplateType, queryVO.getDocTemplateType()));
            if (Objects.nonNull(docTemplate)) {
                AppendixResultVO appendixResultVO = appendixService.getByBiz(docTemplate.getId(), AppendixType.Complaint.COMPLAINT__OFFICE__FILE);
                return OfficeInitVO.builder().appId(officeProperties.getAppId()).fileId(docTemplate.getId().toString()).url(fileService.findUrlById(appendixResultVO.getId())).build();
            }
        }
        long docId = IdUtil.getSnowflake().nextId();
        DocTemplate docTemplate = DocTemplate.builder()
                .name(queryVO.getName()).version(1)
                .caseId(queryVO.getCaseId())
                .docType(queryVO.getDocType())
                .applyParty(queryVO.getApplyParty())
                .partyType(queryVO.getPartyType())
                .caseUserId(queryVO.getCaseUserId())
                .docTemplateType(queryVO.getDocTemplateType()).build();
        docTemplate.setId(docId);
        docTemplateService.getSuperManager().save(docTemplate);
        OfficeInitVO officeInitVO = OfficeInitVO.builder().appId(officeProperties.getAppId()).fileId(Convert.toStr(docId)).url(officeProperties.getTemplateUrl()).build();
        if (Objects.nonNull(queryVO.getCaseId()) && Objects.nonNull(queryVO.getId())) {
            //案件模版第一次编辑的时候，返回模版的URL
            AppendixResultVO appendixResultVO = appendixService.getByBiz(queryVO.getId(), AppendixType.Complaint.COMPLAINT__OFFICE__FILE);
            officeInitVO.setUrl(fileService.findUrlById(appendixResultVO.getId()));
        }
        return officeInitVO;
    }

}
